package com.xuzimian.globaldemo.spring.springwebflux.config;


import org.springframework.boot.web.reactive.result.view.MustacheViewResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.CacheControl;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerTypePredicate;
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
import org.springframework.web.reactive.config.*;

import java.util.concurrent.TimeUnit;

@Configuration
@EnableWebFlux
public class WebFluxConfig implements WebFluxConfigurer {


    /**
     * 路径匹配:
     * Spring WebFlux使用路径模式的解析表示，即PathPattern以及传入请求路径即RequestPath，
     * 这样就不需要指示是否解码请求路径，也不需要删除分号内容，因为PathPattern现在可以访
     * 问解码的路径段值并安全匹配。
     * <p>
     * Spring WebFlux也不支持后缀模式匹配，所以只有两个次要选项可以自定义相关的路径匹配 - 无论是否匹配尾部斜杠
     * （默认为true）以及匹配是否区分大小写（false）
     *
     * @param configurer
     */
    @Override
    public void configurePathMatching(PathMatchConfigurer configurer) {
        configurer.setUseCaseSensitiveMatch(true) //设置启用大小写匹配
                .setUseTrailingSlashMatch(false)  //设置不启用尾斜杠匹配
                .addPathPrefix("/api", HandlerTypePredicate.forAnnotation(RestController.class));
    }

    /**
     * 全局跨域配置
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST")
                .allowCredentials(true).maxAge(3600);
    }

    /**
     * 静态资源
     * 给定以"/resources"开头的请求，相对路径用于在类路径上查找和提供相对于"/static"的静态资源。
     * 将为未来1年的资源提供资源，以确保最大限度地利用浏览器缓存和减少浏览器发出的HTTP请求。
     * 还会对Last-Modified头进行评估，如果存在，则返回304状态码
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
//        //给websocket 的客户端 html 文件 地址映射
//        registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/");

        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/public", "classpath:/static/")
                .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS));
    }


    /**
     * HTTP消息编解码器:
     *
     * @param configurer ServerCodeConfigurer提供一组默认的读写器。可以使用它添加更多的读写器，
     *                   自定义默认的读写器，或者完全替换默认的读写器。
     */
    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {

    }

    /**
     * 视图解析器
     *
     * @param registry
     */
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {

    }



    /**
     * 内容类型解析器:可以从请求中配置Spring WebFlux如何确定@Controller所请求的媒体类型。
     * 默认情况下，只有“Accept”标头被检查，但也可以启用基于查询参数的策略
     *
     * @param builder
     */
    @Override
    public void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {

    }

    /**
     * 注册自定义格式化器和转换器
     *
     * @param registry
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
    }

    /**
     * 自定义全局Validator(验证器)实例，可以在本地注册Validator
     *
     * @return
     */
    @Override
    public Validator getValidator() {
        return null;
    }

//    @Bean
//    public WebHandler webHandler(ApplicationContext applicationContext) {
//        DispatcherHandler dispatcherHandler = new DispatcherHandler(applicationContext);
//        return dispatcherHandler;
//    }


}